/**Jakub Pilch
 * Informatyka IEiT
 * grupa 4, rok I.
 */
package calculate;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;

/**Klasa SciExecutors okresla JPanel z przyciskami dzialan naukowego
 * kalkuatora oraz zapewnia obsluge tych przyciskow.
 */

class SciExecutors extends JPanel {
    
    JButton plus,minus,div,multi,equal,root, pm;
    JButton sin,cos,tan,log,minone;
    JCheckBox inv;
    DecimalFormat df = new DecimalFormat("#0.00000");//do formatowania double.
    static boolean firstuse = true;
    
    /*Obsluga klikniecia przycisku dzialania*/
    private ActionListener count = new ActionListener(){
        public void actionPerformed(ActionEvent a){
            if(!firstuse)
                equation();
            firstuse = false;
             String txt = ((JButton)a.getSource()).getText();
             Calculate.ssig = txt.charAt(0);
             
             if (Calculate.ssig == 's'){                 //wyjatek: pierwiastkowanie.
                 if (Calculate.snbr1 >= 0){
                    Calculate.sresult = Math.sqrt(Calculate.snbr1);
                    Calculate.l2.setText(df.format(Calculate.sresult));
                    Calculate.snbr1 = Calculate.sresult;
                    Calculate.snbr2 = 0;
                 }
                 else{
                      JOptionPane.showMessageDialog(new JFrame(),
                                    "Niedozwolona operacja: pierwiastkowanie ujemnej liczby.",
                                    "Blad obliczen", JOptionPane.ERROR_MESSAGE);
                         reset();
                         Calculate.l2.setText(df.format(Calculate.snbr1));
                         return;
                 }
             }
             
             SNumbers.eqwait = true;
             SNumbers.licznik = 0;
             SNumbers.counter = 0.1f;
             SNumbers.doted = false;
        }
    };
    
    /*Obsluga klikniecia przycisku '='*/
    private ActionListener equate = new ActionListener(){
        public void actionPerformed(ActionEvent a){
            equation();
            firstuse = true;
        }
    };
    
       /*Oblsuga przycisku zmiany znaku*/    
        private ActionListener plusminus = new ActionListener(){
            public void actionPerformed(ActionEvent a){
                if (SNumbers.eqwait){
                    Calculate.snbr2 *= -1;
                    Calculate.l2.setText(df.format(Calculate.snbr2));
                }
                else{
                    Calculate.snbr1 *= -1;
                    Calculate.l2.setText(df.format(Calculate.snbr1));
                }
            }
    };
        
   private ActionListener func = new ActionListener(){
        public void actionPerformed(ActionEvent a){
            if(!firstuse)
                equation();
            firstuse = false;
             String txt = ((JButton)a.getSource()).getText();
             
             if (txt.equals("sin(x)")){             //sinus rozrozniany od sqrt.
                    if (!inv.isSelected())
                        Calculate.sresult = Math.sin(Calculate.snbr1);
                    else 
                        if(Calculate.snbr1 >= -1 && Calculate.snbr1 <= 1)
                            Calculate.sresult = Math.asin(Calculate.snbr1);
                        else{
                            JOptionPane.showMessageDialog(new JFrame(),
                               "Arcsinus obliczany wylacznie z zakresu [-1,1]. ",
                               "Blad obliczen", JOptionPane.ERROR_MESSAGE);
                            reset();
                            Calculate.l2.setText(df.format(Calculate.snbr1));
                            return;    
                        }         
             }
             
             if (txt.equals("cos(x)")){             //cosinus - szczeg. przypadek.
                 if (!inv.isSelected())
                    Calculate.sresult = Math.cos(Calculate.snbr1);
                 else 
                    if(Calculate.snbr1 >= -1 && Calculate.snbr1 <= 1)
                        Calculate.sresult = Math.acos(Calculate.snbr1);
                    else{
                        JOptionPane.showMessageDialog(new JFrame(),
                           "Arccosinus obliczany wylacznie z zakresu [-1,1]. ",
                           "Blad obliczen", JOptionPane.ERROR_MESSAGE);
                        reset();
                        Calculate.l2.setText(df.format(Calculate.snbr1));
                        return;    
                        }         
             }
             
             if (txt.equals("tan(x)")){             //tangens - szczeg. przyp.
                 if (inv.isSelected())
                     Calculate.sresult = Math.atan(Calculate.snbr1);
                 else if (Calculate.snbr1>-Math.PI/2 && Calculate.snbr1<Math.PI/2){
                    Calculate.sresult = Math.tan(Calculate.snbr1);
                 }
                 else{
                     JOptionPane.showMessageDialog(new JFrame(),
                                "Tangens obliczany wylacznie z zakresu (-pi/2,pi/2). ",
                                "Blad obliczen", JOptionPane.ERROR_MESSAGE);
                     reset();
                     Calculate.l2.setText(df.format(Calculate.snbr1));
                     return;    
                 }
             }
             
             if (txt.equals("ln(x)")){             //logarytm dziesietny.
                 if(Calculate.snbr1 > 0){
                    Calculate.sresult = Math.log(Calculate.snbr1);
                 }
                 else{
                      JOptionPane.showMessageDialog(new JFrame(),
                                "Blad obliczen: logarytm z liczby niedodatniej.",
                                "Blad obliczen", JOptionPane.ERROR_MESSAGE);
                     reset();
                     Calculate.l2.setText(df.format(Calculate.snbr1));
                     return;
                 }
             }
             
             if (txt.equals("1/x")){             //odwrotnosc.
                    if(Calculate.snbr1 != 0){
                       Calculate.sresult = 1/Calculate.snbr1;
                    }
                    else{
                     JOptionPane.showMessageDialog(new JFrame(),
                                "Nie mozna obliczyc odwrotnosci zera.",
                                "Blad obliczen", JOptionPane.ERROR_MESSAGE);
                     reset();
                     Calculate.l2.setText(df.format(Calculate.snbr1));  
                    }
             }
             Calculate.l2.setText(df.format(Calculate.sresult));
             Calculate.snbr1 = Calculate.sresult;
             Calculate.snbr2 = 0;
        }
    };
   
   /*obsługa listy rozwijanej JComboBox.*/
   private ActionListener boxie = new ActionListener(){
        public void actionPerformed(ActionEvent a){
            JComboBox bx = (JComboBox)a.getSource();
            String val = (String)bx.getSelectedItem();
            
                if (val.equals("pi"))
                    addVal(Math.PI);
                else if (val.equals("pi/2"))
                    addVal(Math.PI/2);
                else
                    addVal(Math.E);
       }
   };
   
   private void addVal (double x){
       if (SNumbers.eqwait){
                    Calculate.snbr2 = x;
                    Calculate.l2.setText(df.format(Calculate.snbr2));
                }
                else{
                    Calculate.snbr1 = x;
                    Calculate.l2.setText(df.format(Calculate.snbr1));
                }
   };

    
    protected SciExecutors(){
        setLayout(new GridLayout(1,3));
        
        JPanel FuncPan = new JPanel();
        FuncPan.setLayout(new GridLayout(6,1));
        JPanel GrdPan = new JPanel();
        GrdPan.setLayout(new GridLayout(3,2));
        
        plus = new JButton("+");        //inicjalizacja.
        minus = new JButton("-");
        div = new JButton("/");
        multi = new JButton("X");
        equal = new JButton("=");
        root = new JButton ("sqrt");
        pm = new JButton("+/-");
        
        sin = new JButton("sin(x)");
        cos = new JButton("cos(x)");
        tan = new JButton("tan(x)");
        log = new JButton("ln(x)");
        minone = new JButton ("1/x");
        
        String []labels = {"pi", "pi/2", "e"};
        JComboBox box = new JComboBox(labels);
        inv = new JCheckBox("Inverse");
        
        
        plus.addActionListener(count); //dodanie obslugi zdarzen.
        minus.addActionListener(count);
        div.addActionListener(count);
        multi.addActionListener(count);
        equal.addActionListener(equate);
        root.addActionListener(count);
        pm.addActionListener(plusminus);
        box.addActionListener(boxie);
        
        sin.addActionListener(func);    //obsluga funkcji.
        cos.addActionListener(func);
        tan.addActionListener(func);
        log.addActionListener(func);
        minone.addActionListener(func);
        
        GrdPan.add(plus);
        GrdPan.add(minus);
        GrdPan.add(div);
        GrdPan.add(multi);
        GrdPan.add(root);
        GrdPan.add(pm);
        
        JPanel dubl = new JPanel();
        dubl.setLayout(new GridLayout(1,2));
        dubl.add(box);
        dubl.add(inv);
        
        FuncPan.add(sin);
        FuncPan.add(cos);
        FuncPan.add(tan);
        FuncPan.add(log);
        FuncPan.add(minone);
        FuncPan.add(dubl);

        JPanel dblt = new JPanel();
        dblt.setLayout(new GridLayout(2,1));
        dblt.add(GrdPan);
        dblt.add(equal);
        
        
        add(dblt);
        add(FuncPan);
    }
    
    private void equation(){                    //obliczanie wyniku dzialania.
        switch(Calculate.ssig){
                case '+':
                    Calculate.sresult = Calculate.snbr1 + Calculate.snbr2;
                    break;
                case '-':
                    Calculate.sresult = Calculate.snbr1 - Calculate.snbr2;
                    break;
                case 'X':
                    Calculate.sresult = Calculate.snbr1 * Calculate.snbr2;
                    break;
                case '/':
                    if (Calculate.snbr2 == 0){   //obsluga dzielenia przez 0.
                        JOptionPane.showMessageDialog(new JFrame(),
                                    "Niedozwolona operacja: dzielenie przez 0.",
                                    "Blad obliczen", JOptionPane.ERROR_MESSAGE);
                         reset();
                         Calculate.l2.setText(df.format(Calculate.snbr1));
                         break;
                    }
                    Calculate.sresult = Calculate.snbr1 / Calculate.snbr2;
                    break;
                default:
                    Calculate.sresult = Calculate.snbr1;
                    break;
            }
            Calculate.l2.setText(df.format(Calculate.sresult));
            Calculate.snbr1 = Calculate.sresult;
            Calculate.snbr2 = 0;
    }
    
    
    protected void reset(){
        Calculate.snbr1 = 0;                     //reset danych.
        Calculate.snbr2 = 0;
        Calculate.sresult = 0;
        SNumbers.counter = 0.1f;
        SNumbers.licznik = 0;
        Calculate.ssig='0';
        firstuse = true;
        SNumbers.doted = false;
        SNumbers.eqwait = false;                 //tutaj BRAK WYPISANIA 0!
        
    }
}